<template>
  <d2-container class="template">
    <el-row :gutter="20">
      <el-col style="width: 150px">
        <el-button
          type="primary"
          icon="el-icon-circle-plus-outline"
          @click="handleAdd"
          class="template-add"
          >新增模板</el-button
        >
      </el-col>
      <el-form :model="formSearch" ref="formSearchRef" label-width="80px">
        <el-col :span="6">
          <el-form-item label="项目名称" prop="projectId">
            <el-select
              filterable
              v-model="formSearch.projectId"
              placeholder="请选择项目名称"
              @change="changeTableNameByProjectId"
              class="template-select"
            >
              <el-option
                v-for="item in projectList"
                :key="item.id"
                :label="item.name"
                :value="item.id"
              >
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="模板名称" prop="name">
            <el-input
              placeholder="请输入模板名称"
              v-model="formSearch.name"
            ></el-input>
          </el-form-item>
        </el-col>
        <el-col style="width: 150px">
          <el-button
            type="primary"
            icon="el-icon-search"
            @click="handleSearch"
            class="template-add"
            >搜索</el-button
          >
        </el-col>
      </el-form>
    </el-row>

    <!-- 表格 -->
    <el-table
      :data="tableList"
      :max-height="fullHeight"
      :row-class-name="tableRowClassName"
      v-loading="tableLoading"
    >
      <el-table-column width="250" prop="name" label="模板名称">
      </el-table-column>
      <el-table-column prop="fileName" label="文件名称"> </el-table-column>
      <el-table-column prop="filePath" label="文件路径"> </el-table-column>
      <el-table-column width="100" label="操作">
        <template slot-scope="{ row }">
          <el-popconfirm
            placement="top"
            confirm-button-text="确定"
            cancel-button-text="取消"
            icon="el-icon-info"
            icon-color="red"
            confirm-button-type="danger"
            title="确定删除吗？"
            @confirm="handleRemove(row)"
          >
            <el-button
              circle
              type="danger"
              slot="reference"
              size="small"
              icon="el-icon-delete"
              class="template-btn-delete"
            ></el-button>
          </el-popconfirm>

          <el-button
            type="primary"
            size="small"
            icon="el-icon-edit"
            circle
            @click="handleUpdate(row)"
          ></el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-pagination
      background
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="currentPage"
      :page-sizes="[10, 15, 20, 30]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      :hide-on-single-page="true"
      v-if="tableList.length > 0"
      class="template-page"
    >
    </el-pagination>

    <!--  新增、编辑弹窗 -->
    <el-dialog
      :title="isAdd ? '新增模板' : '编辑模板'"
      width="90%"
      :visible.sync="dialogFormVisible"
      :close-on-press-escape="false"
      :close-on-click-modal="false"
      :before-close="cancelDialogFormVisible"
      top="5px"
      class="template-dialog"
    >
      <el-row :gutter="30">
        <el-col :span="16" class="template-dialog-left">
          <p class="template-velocity-title">模板表单</p>
          <el-form
            :model="form"
            :rules="rules"
            ref="formRef"
            label-width="80px"
            inline
          >
            <el-form-item label="项目名称" prop="projectId">
              <el-select
                filterable
                v-model="form.projectId"
                placeholder="请选择项目名称"
                @change="changeTableNameByProjectId"
                class="template-select"
              >
                <el-option
                  v-for="item in projectList"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                >
                </el-option>
              </el-select>
            </el-form-item>

            <el-form-item
              label="关联表"
              prop="tableName"
              v-show="form.projectId"
            >
              <el-select
                filterable
                v-model="form.tableName"
                placeholder="请选择关联表"
                class="template-select"
              >
                <el-option
                  v-for="item in surfaceList"
                  :key="item.tableName"
                  :label="item.tableName"
                  :value="item.tableName"
                >
                </el-option>
              </el-select>
            </el-form-item>

            <el-form-item label="模板名称" prop="name">
              <el-input
                v-model="form.name"
                placeholder="请输入模板名称"
                maxlength="64"
                show-word-limit
              />
            </el-form-item>

            <el-form-item label="文件目录" prop="filePath">
              <el-input
                v-model="form.filePath"
                placeholder="为空则是模板名称"
                maxlength="64"
                show-word-limit
              />
            </el-form-item>

            <el-form-item label="文件名称" prop="fileName">
              <el-input
                v-model="form.fileName"
                placeholder="可使用 velocity 变量"
                maxlength="100"
                show-word-limit
              />
            </el-form-item>

            <el-form-item
              label="模板内容"
              prop="content"
              class="template-content-codemiror"
            >
              <codemirror
                ref="editor"
                v-model="form.content"
                :options="cmOptions"
              ></codemirror>
            </el-form-item>
          </el-form>
        </el-col>
        <el-col :span="8">
          <p>
            <span class="template-velocity-title">Velocity变量</span>
            <span class="template-velocity-tip">点击变量直接插入模板内容</span>
          </p>

          <el-tabs v-model="tabActive" @tab-click="handleClick">
            <el-tab-pane
              v-for="item in velocityTemplateList"
              :key="item.expression"
              :label="item.text"
            >
              <div v-for="ele in item.children" :key="ele.expression">
                <p>
                  <span
                    @click="insertTemplateVelocity(ele.expression)"
                    class="template-velocity-params"
                    >{{ ele.expression }}</span
                  >
                  <span>{{ ele.text }}</span>
                </p>
              </div>
            </el-tab-pane>
          </el-tabs>
        </el-col>
      </el-row>

      <span slot="footer">
        <el-button @click="cancelDialogFormVisible">取消</el-button>
        <el-button @click="handlePreviewTemplate">预览模板</el-button>
        <el-button type="primary" :loading="submitLoading" @click="submit"
          >确定</el-button
        >
      </span>
    </el-dialog>

    <el-drawer
      title="预览模板"
      :visible.sync="drawerVisible"
      :direction="rtl"
      :before-close="handleCloseDrawer"
      class="template-preview-content"
    >
      <span
        class="template-copy-btn"
        v-clipboard:copy="previewContent"
        v-clipboard:success="copyTextSuccess"
        v-clipboard:error="copyTextError"
        >复制</span
      >
      <codemirror v-model="previewContent" :options="cmOptions"></codemirror>
    </el-drawer>
  </d2-container>
</template>

<script>
import api from "@/api";
import { codemirror } from "vue-codemirror";
import "codemirror/theme/neat.css";
require("codemirror/mode/velocity/velocity");

export default {
  name: "template",
  components: { codemirror },
  data() {
    return {
      cmOptions: {
        mode: "text/velocity",
        theme: "neat",
        lineNumbers: true,
        readOnly: false
      },
      isVelocityBarFixed: false,
      fullHeight: document.documentElement.clientHeight - 250,
      isAdd: false,
      tabActive: "0",
      submitLoading: false,
      dialogFormVisible: false,
      drawerVisible: false,
      previewContent: "",
      tableList: [],
      projectList: [],
      surfaceList: [],
      velocityTemplateList: [],
      tableLoading: false,
      total: 0,
      pageSize: 10,
      currentPage: 1,
      formSearch: {
        projectId: "",
        name: ""
      },
      form: {
        id: "",
        projectId: "",
        tableName: "",
        name: "",
        filePath: "",
        fileName: "",
        content: ""
      },
      rules: {
        projectId: [
          {
            required: true,
            message: "请选择项目名称",
            trigger: "change"
          }
        ],
        name: [
          {
            required: true,
            message: "请输入模板名称",
            trigger: "blur"
          }
        ],
        fileName: [
          {
            required: true,
            message: "请输入文件名称",
            trigger: "blur"
          }
        ],
        content: [
          {
            required: true,
            message: "请输入模板内容",
            trigger: "blur"
          }
        ]
      }
    };
  },
  mounted() {
    const projectId = this.$route.params.projectId;
    this.formSearch.projectId = projectId ? projectId : "";
    getProjectList(this, 1);
  },
  methods: {
    // 表格斑马线
    tableRowClassName({ row, rowIndex }) {
      if (rowIndex % 2 >= 1) {
        return "select-row";
      }
      return "";
    },

    // 表格分页
    handleSizeChange(val) {
      this.pageSize = val;
      getTableList(this);
    },

    handleCurrentChange(val) {
      this.currentPage = val;
      getTableList(this);
    },

    // 项目名称改变 获取预览表
    changeTableNameByProjectId(value) {
      getSurfaceList(this, value);
    },

    // 删除模板
    handleRemove(row) {
      deleteTemplate(this, row);
    },

    // 搜索列表
    handleSearch() {
      this.pageSize = 10;
      this.currentPage = 1;
      getTableList(this);
    },

    // 新增模板按钮点击
    handleAdd() {
      this.isAdd = true;
      this.form.id = "";
      this.dialogFormVisible = true;
      this.tabActive = "0";
      velocityTemplate(this);
    },

    // 编辑模板按钮点击
    handleUpdate(row) {
      this.isAdd = false;
      this.form.id = row.id;
      this.dialogFormVisible = true;
      this.tabActive = "0";
      velocityTemplate(this);
      updateInitTemplate(this, row.id);
      if (this.form.projectId) {
        this.changeTableNameByProjectId(this.form.projectId);
      }
    },

    // 预览模板内容
    handlePreviewTemplate() {
      this.$refs.formRef.validate(valid => {
        if (valid) {
          previewTemplateContent(this, { ...this.form });
          this.drawerVisible = true;
        }
      });
    },

    // 复制模板内容成功时的回调函数
    copyTextSuccess(e) {
      this.$message.success("内容已复制到剪切板！");
    },
    // 复制模板内容失败时的回调函数
    copyTextError(e) {
      this.$message.error("抱歉，复制失败！");
    },

    // 关闭抽屉
    handleCloseDrawer() {
      this.previewContent = "";
      this.drawerVisible = false;
    },

    // 点击变量插入到模板内容
    async insertTemplateVelocity(value) {
      const codemirror = this.$refs.editor.codemirror;
      codemirror.replaceSelection(value);
      codemirror.focus();
    },

    // 取消弹窗
    cancelDialogFormVisible() {
      this.resetDialogForm();
      this.dialogFormVisible = false;
    },

    // 重置表单
    resetDialogForm() {
      this.$refs.formRef.resetFields();
    },

    // 新增弹窗提交
    submit() {
      this.$refs.formRef.validate(valid => {
        if (valid) {
          this.submitLoading = true;
          this.isAdd
            ? addTemplate(this, { ...this.form })
            : updateTemplate(this, { ...this.form });

          this.resetDialogForm();
          this.submitLoading = false;
          this.dialogFormVisible = false;
        }
      });
    },

    // 重置
    resetForm(formName) {
      this.$refs[formName].resetFields();
    }
  }
};

// 模板列表
async function getTableList(that) {
  that.tableLoading = true;
  const data = {
    name: that.formSearch.name,
    projectId: that.formSearch.projectId,
    pageSize: that.pageSize,
    currentPage: that.currentPage
  };
  let res = await api.templateTableList(data);
  that.tableLoading = false;
  that.tableList = res?.records || [];
  that.total = res?.total;
}

// 项目名称列表
async function getProjectList(that, type) {
  let res = await api.templateProjectList();
  that.projectList = res || [];
  if (type === 1 && res.length > 0 && !that.formSearch.projectId) {
    that.formSearch.projectId = res[0].id;
  }
  getTableList(that);
}

// 关联表名称列表
async function getSurfaceList(that, data) {
  let res = await api.templateSurfaceList(data);
  that.surfaceList = res || [];
}

// 新增模板
async function addTemplate(that, data) {
  let res = await api.templateAdd(data);
  getTableList(that);
  that.$message({
    message: "新增成功",
    type: "success"
  });
}

// 删除模板
async function deleteTemplate(that, data) {
  let res = await api.templateDelete(data);
  getTableList(that);
  that.$message({
    message: "删除成功",
    type: "success"
  });
}

// 编辑初始化
async function updateInitTemplate(that, data) {
  let res = await api.templateUpdateInit(data);
  that.form = { ...res };
}

// 编辑
async function updateTemplate(that, data) {
  let res = await api.templateUpdate(data);
  if (res?.code === "0") {
    getTableList(that);
    that.$message({
      message: "修改成功",
      type: "success"
    });
  }
}

// 预览模板内容
async function previewTemplateContent(that, data) {
  let res = await api.templatePreview(data);
  that.previewContent = res;
}

// templateVelocity
async function velocityTemplate(that) {
  let res = await api.templateVelocity(that.formSearch);
  that.velocityTemplateList = res;
}
</script>

<style lang="scss">
.template {
  .el-table .select-row {
    background-color: #f3f6f9;
  }

  .template-add {
    margin-bottom: 15px;
  }

  .template-btn-delete {
    margin-right: 10px;
  }

  .template-select {
    width: 100%;
  }

  .template-preview-btn:hover {
    color: #fff;
  }

  .template-preview-content .el-drawer__open .el-drawer__header {
    margin-bottom: 0;
    padding: 15px 20px !important;
  }

  .template-preview-content .el-drawer__open .el-drawer__body {
    padding: 0 0 20px 0;
  }

  .template-velocity-params {
    margin-right: 20px;
    color: #1e90ff;
    font-weight: 800;
    text-decoration: underline;
    cursor: pointer;
  }

  .template-dialog .el-dialog__body {
    padding: 0 20px;
  }

  .template-dialog .el-dialog__footer {
    padding-top: 0 !important;
  }

  .template-velocity-title {
    font-weight: 900;
    font-size: 16px;
    margin-right: 10px;
  }

  .template-velocity-tip {
    font-size: 12px;
    color: #999;
  }

  .template-copy-btn {
    cursor: pointer;
    position: absolute;
    top: 17px;
    right: 65px;
    font-size: 14px;
    color: #1e90ff;
  }

  .template-page {
    margin-top: 10px;
  }

  .template-content-codemiror {
    display: block !important;
  }

  .template-content-codemiror .el-form-item__content {
    line-height: 20px !important;
    width: 85%;
    border: 1px solid #eee;
    border-radius: 2px;
  }

  .template-dialog-left .el-form--inline .el-form-item__content {
    min-width: 250px !important;
  }

  .template-content-codemiror .CodeMirror {
    height: 575px !important;
  }

  .template-preview-content .CodeMirror {
    height: 100% !important;
  }
}
</style>
